package cate.game.client.msg;

import cate.game.common.scanner.GameScanner;
import cate.game.common.scanner.IScanner;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class MsgAnnotationHandler implements IScanner {
    public MsgAnnotationHandler() {
        GameScanner.registScanner(this);
    }

    @Override
    public boolean match(Class<?> clazz) {
        return MsgInput.class.isAssignableFrom(clazz) && !clazz.isInterface() && !Modifier.isAbstract(clazz.getModifiers());
    }

    @Override
    public void handle(Class<?> clazz) {
        @SuppressWarnings("unchecked")
        Pack pack = new Pack((Class<? extends MsgInput>) clazz);
        try {
            MsgInput inputInstance = pack.inputClz.getConstructor().newInstance();
            MsgConfig conf = inputInstance.conf();
            if(conf == null) {
                log.error("{}忘记返回对应的MsgConfig了", clazz);
                return;
            }
            final String key = genMsgInputKey(conf.a, conf.b);
            this.msgInputMap.put(key, pack);
        } catch (Exception e) {
            log.error("生产MsgInput出错{}", clazz.getName(), e);
        }
    }

    @Override
    public void afterScan() {
        // nothing
    }

    public static final class Pack {
        public Class<? extends MsgInput> inputClz;
        public Pack() {}
        public Pack(Class<? extends MsgInput> clazz) {
            this.inputClz = clazz;
        }
    }

    // Map<a_b, clz>
    private Map<String, Pack> msgInputMap = new HashMap<>();

    private static String genMsgInputKey(int msgIdA, int msgIdB) {
        return msgIdA + "-" + msgIdB;
    }

    public MsgInput genMsgInput(GameMsg msg) {
        final String key = genMsgInputKey(msg.idA, msg.idB);
        try {
            Pack pack = msgInputMap.get(key);
            return msg.decodeJson(pack.inputClz);
        } catch (Exception e) {
            log.error("找不到消息{}", key, e);
            return null;
        }
    }
}
